﻿///<reference path="/scripts/jQuery.js"/>
///<reference path="/scripts/knockout-2.2.1.js"/>
///<reference path="/scripts/underscore-ko-1.2.2.js"/>
///<reference path="/scripts/underscore.js"/>

//Reserve seat structure
var BusBookingInfo = function (selectedSeats, fromCityId, fromCityName, toCityId, toCityName, journeyDate,
                            journeyTime, arrivalDate, arrivalTime, bordingPoint, bordingPointTime, busOperator, busType) {
    this.FromCityId = fromCityId;
    this.FromCityName = fromCityName;
    this.ToCityId = toCityId;
    this.ToCityName = toCityName;
    this.JourneyDate = journeyDate;
    this.JourneyTime = journeyTime;
    this.ArrivalDate = arrivalDate;
    this.ArrivalTime = arrivalTime;
    this.BordingPoint = bordingPoint;
    this.BordingPointTime = bordingPointTime;
    this.BusOperator = busOperator;
    this.BusType = busType;
    this.SelectedSeats = selectedSeats;
};

function busResultViewModel() {
    var self = this;

    self.busResultModel = ko.observable();
    self.busResults = ko.observableArray([]);
    self.availableFares = ko.observableArray([]);
    self.fromCityId = ko.observable();
    self.fromCityName = ko.observable();
    self.toCityId = ko.observable();
    self.toCityName = ko.observable();
    self.journeyDate = ko.observable();

    //Select Sheet click
    self.selectedBus = ko.observable();

    //Min & Max Slider
    self.minFare = ko.observable();
    self.minFare.subscribe(function (newValue) {
        filterResults();
    });

    self.maxFare = ko.observable();
    self.maxFare.subscribe(function (newValue) {
        filterResults();
    });


    //Bus Types Checked Items
    self.busTypeCheckedItems = ko.observableArray();
    self.busTypeCheckedItems.subscribe(function (newValue) {
        //filterByBusType(newValue);
        filterResults();
    });

    //Bus Operators Checked Items
    self.busOperatorCheckedItems = ko.observableArray();
    self.busOperatorCheckedItems.subscribe(function (newValue) {
        //filterByBusOperatior(newValue);
        filterResults();
    });

    //Sortin option
    self.sortingColumns = ko.observableArray(["CompanyName", "Fare"]);
    self.sortDirection = ko.observable(false);
    self.sortByColumnName = function (colName) {
        self.sortDirection(!self.sortDirection());
        var result = self.busResultModel().BusResults.sort(function (obj1, obj2) {
            if (obj1[colName] == obj2[colName]) return 0;
            return (obj1[colName] < obj2[colName]) ? -1 : 1;
        });

        if (self.sortDirection())
            self.busResults(result);
        else
            self.busResults(result.reverse());
    };

    //Show error message
    self.isError = ko.observable(false);
    self.errorMessage = ko.observable();

    self.busSeatMapModel = ko.observable();
    self.selectedBordingPoint = ko.observable();

    //Booking
    self.bookBus = function () {
        self.isError(false);
        self.errorMessage("");

        if (!self.selectedBordingPoint()) {
            self.isError(true);
            self.errorMessage("Please select bording pint!");
            return;
        }

        var seats = "";
        ko.utils.arrayForEach(self.selectedSeats(), function (item) {
            seats += item.seatNo + "~";
        });

        var bus = self.selectedBus();
        var bookingInfo = new BusBookingInfo(self.selectedSeats(), self.fromCityId(), self.fromCityName(),
                                self.toCityId(), self.toCityName(), self.journeyDate(), bus.DepartureTime, bus.ArrivalDate,
                                bus.ArrivalTime, "Coimbatore Bus Stand", "12 : 10", bus.CompanyName, bus.Amenities);

        $.ajax({
            url: '/bus/result',
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            data: ko.toJSON(bookingInfo),
            success: function (data, textStatus, xhr) {
                window.location.href = data.redirectToUrl;
                /*$.post(data.redirectToUrl, bookingInfo, function () {
                    
                });*/
            }
        });
    };

    //Seats mapping
    self.seatTop = function (data) {
        return (data.Row * 26) + 'px';
    };

    self.seatLeft = function (data) {
        if(data.IsSleeper)
            return (data.Column * 48) + 'px';
        else
            return (data.Column * 24) + 'px';
    };

    self.selectedSeats = ko.observableArray([]);

    self.selectSheet = function (data, event) {
        if (!data.IsAvailable) return; //Seat is already booked

        var match = ko.utils.arrayFirst(self.selectedSeats(), function (item) {
            return data.SeatNo == item.seatNo;
        });

        var length = self.selectedSeats().length;
        if (!match && length > 5) return true;

        if (!match) {
            self.selectedSeats.push({ fare: data.Fare, seatNo: data.SeatNo });
            $(event.target).attr('class', data.IsSleeper ? 'selectedSleeper' : 'selectedSeat');
        }
        else {
            self.selectedSeats.remove(match);
            $(event.target).attr('class', data.IsSleeper ? 'availableSleeper' : 'availableSeat');
        }
    };

    self.selectedSeatsAmount = function () {
        var total = 0;
        ko.utils.arrayForEach(self.selectedSeats(), function (item) {
            total += item.fare;
        });

        return total;
    };

    self.seatCss = function (data) {
        var css;

        if (data.IsSleeper) {
            if (data.IsAvailable && data.Gender == "M")
                css = "availableSleeper";
            else if (data.IsAvailable && data.Gender == "F")
                css = "availableSleeper"; //TODO: for ladies
            else if (data.Gender == "F")
                css = "bookedLadiesSleeper";
            else
                css = "bookedSleeper";
        }
        else {

            if (data.IsAvailable && data.Gender == "M")
                css = "availableSeat";
            else if (data.IsAvailable && data.Gender == "F")
                css = "availableSeat"; //TODO: for ladies
            else if (data.Gender == "F")
                css = "bookedLadiesSeat";
            else
                css = "bookedSeat";
        }

        return css;
    };
}

//View Sheet
ko.bindingHandlers.viewSheet = {
    init: function (element, valueAccessor) {
        var data = valueAccessor();
        //make sure that we clear the observable no matter how the modal is closed
        $(element).modal({ show: false }).on("hidden", function () {
            if (ko.isWriteableObservable(data)) {
                data(null);
            }
        });

        //wrap the real "with" binding
        return ko.bindingHandlers["with"].init.apply(this, arguments);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var data = ko.utils.unwrapObservable(valueAccessor());
        //show or hide the modal depending on whether the associated data is populated
        //wrap the real "with" binding

        if (data) {
            bindSeatMap(data.RouteScheduleId, element);
        }

        //Clear selected seats
        vm.selectedSeats([]);

        $(element).modal(data ? "show" : "hide");

        return ko.bindingHandlers["with"].update.apply(this, arguments);
    }
};


//Selecte particular seat

function bindModel(data) {
    //Bus Model
    vm.busResultModel(data);
    //Bus Results
    vm.busResults(data.BusResults);
    //Bus Types
    vm.busTypeCheckedItems(data.BusTypes);
    //Bus Operatos
    vm.busOperatorCheckedItems(data.BusOperators);
    //Available Fares
    vm.availableFares(data.AvailableFares);
    //Min/Max Fares
    vm.minFare(data.MinFare);
    vm.maxFare(data.MaxFare);
    //Search data
    vm.fromCityId(data.FromCityId);
    vm.fromCityName(data.FromCityName);
    vm.toCityId(data.ToCityId);
    vm.toCityName(data.ToCityName);
    vm.journeyDate(data.JourneyDate);

    showSlider();
}


function showSlider() {
    $("#slider-range").slider({
        range: true,
        min: vm.minFare(),
        max: vm.maxFare(),
        step: 1,
        values: [vm.minFare(), vm.maxFare()],
        slide: function (event, ui) {
            vm.minFare(ui.values[0]);
            vm.maxFare(ui.values[1]);
        }
    });
}

function formatCurrency(value) {
    return "Rs " + value;
}

function filterResults() {
    var ar = [];
    ko.utils.arrayForEach(vm.busResultModel().BusResults, function (item) {

        //Filter By Bus Type        
        var isBusTypeMatched = false;
        var checkedItem = vm.busTypeCheckedItems();
        for (var i = 0; i < checkedItem.length; i++) {
            isBusTypeMatched = item.BusItemTypes.indexOf(checkedItem[i]) > -1;
            if (isBusTypeMatched) {
                break;
            }
        }

        //Filter By Bus Operator
        var isBusTravelMatched = vm.busOperatorCheckedItems().indexOf(item.CompanyName) > -1;

        //Filter By Min and Max Price
        var isFareRange = (item.Fare >= vm.minFare() && item.Fare <= vm.maxFare());

        if (isBusTypeMatched && isBusTravelMatched && isFareRange) {
            ar.push(item);
        }
    });

    vm.busResults([]);
    vm.busResults(ar);
}

function formatCancellationPolicy(policies) {
    var policy = "";
    for (var i = 0; i < policies.length; i++) {
        policy += "<b>- </b>" + policies[i] + "</br>";
    }

    return policy;
}


function bindSeatMap(routeScheduleId, element) {
    $(document).ready(function () {
        $.getJSON("/api/BusSeatApi/" + routeScheduleId, {
            format: "json"
        }).done(function (data) {
            //Bind Seat Map VM
            vm.busSeatMapModel(data);

            if (data) {
                $(element).find("[rel='popover']").popover({
                    html: true,
                    content: function () {
                        return formatCancellationPolicy(data.CancellationPolicy);
                    }
                });
            }
        });
    });

}